package com.qy.changemachine.mqtt;


import androidx.annotation.WorkerThread;

import com.qy.changemachine.util.Contants;
import com.qy.changemachine.util.LogUtil;

import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import java.util.ArrayList;
import java.util.List;

public class MqttManager {
    private static final String TAG = "MqttManager";
    private MqttClient mqttClient;
    private String broker;
    private String username;
    private String password;
    private String clientId;
    private MqttCallback callback;
    private List<String> unSendMesssage = new ArrayList<>();

    public int maxRetryConnect = 240;
    public int retryConnectCount = 0;
    public int unSendMsgSize =5;

    public MqttManager(String broker, String username, String password, MqttCallback callback, String clientId) {
        this.broker = broker;
        this.username = username;
        this.password = password;
        this.callback = callback;
        this.clientId = clientId;
    }

    @WorkerThread
    public void connect() {
        try {
            MemoryPersistence persistence = new MemoryPersistence();
            mqttClient = new MqttClient(broker, clientId, persistence);
            MqttConnectOptions connOpts = new MqttConnectOptions();
            connOpts.setKeepAliveInterval(5);
            connOpts.setCleanSession(false);
            connOpts.setUserName(username);
            connOpts.setPassword(password.toCharArray());

            LogUtil.INSTANCE.d(TAG, "Connecting to MQTT broker: " + broker);
            mqttClient.connect(connOpts);
            LogUtil.INSTANCE.d(TAG, "Connected to MQTT broker");

            mqttClient.setCallback(callback);

        } catch (MqttException e) {
            LogUtil.INSTANCE.d(TAG, "Reason code: " + e.getReasonCode() + "Message: " + e.getMessage() + "Cause: " + e.getCause());
            try {
                LogUtil.INSTANCE.d(TAG, "MQTT connection exception sleep 2s try again");
                Thread.sleep(2000);
                connect();
            } catch (Exception ex) {
                LogUtil.INSTANCE.d(TAG, "MQTT reconnection exception :" + ex.getMessage());
            }
        }
    }

    public void disconnect() {
        if (mqttClient != null && mqttClient.isConnected()) {
            try {
                mqttClient.disconnect();
                LogUtil.INSTANCE.d(TAG, "Disconnected from MQTT broker");
            } catch (MqttException e) {
                LogUtil.INSTANCE.d(TAG, "Failed to disconnect from MQTT broker:" + e.getMessage());
            }
        }
    }

    public void subscribe(String topic) {
        if (mqttClient != null && mqttClient.isConnected()) {
            try {
                mqttClient.subscribe(topic, 2);
                LogUtil.INSTANCE.d(TAG, "Subscribed to topic: " + topic);
            } catch (MqttException e) {
                LogUtil.INSTANCE.d(TAG, "Failed to subscribe to topic: " + topic + " e:" + e.getMessage());
            }
        }
    }

    public void reconnect() {
        if (mqttClient != null && !mqttClient.isConnected()) {
            connect();
        }
    }

    public boolean publishMessage(String topic, String messageContent) {
        if (mqttClient != null && mqttClient.isConnected()) {
            try {
                // 发送未发送成功的消息
                for (String msg : unSendMesssage) {
                    MqttMessage message = new MqttMessage(msg.getBytes());
                    message.setQos(2); // QoS 可以是 0、1 或 2
                    mqttClient.publish(topic, message);
                    LogUtil.INSTANCE.d(TAG, "Success published no send message to topic: " + topic + "  ==>Message content: " + message);
                }
                unSendMesssage.clear();
                MqttMessage message = new MqttMessage(messageContent.getBytes());
                message.setQos(2); // QoS 可以是 0、1 或 2
                mqttClient.publish(topic, message);
                if (!messageContent.equals(Contants.MQTT_HEADER_MESSAGE)) {
                    LogUtil.INSTANCE.d(TAG, "Success published to topic: " + topic + "  ==>Message content: " + messageContent);
                }
                retryConnectCount=0;
                return true;
            } catch (MqttException e) {
                LogUtil.INSTANCE.d(TAG, "Failed to publish message:" + e.getMessage());
                if (!messageContent.equals(Contants.MQTT_HEADER_MESSAGE) && unSendMesssage.size() <= unSendMsgSize) {
                    unSendMesssage.add(messageContent);
                }
                return false;
            }
        } else {
            if (!messageContent.equals(Contants.MQTT_HEADER_MESSAGE) && unSendMesssage.size() <= unSendMsgSize) {
                unSendMesssage.add(messageContent);
            }
            LogUtil.INSTANCE.d(TAG, "Failed !!! MQTT client is not connected, cannot publish message:"+messageContent);
            retryConnectCount+=1;
            return false;
        }
    }

}